package com.itheima.spring.aop;

import com.itheima.spring.aop.advice.AfterReturningAdvice;
import com.itheima.spring.aop.advice.MethodBeforeAdvice;
import com.itheima.spring.aop.advice.MethodInterceptor;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 责任链式执行增强
 */
public class AopAdviceChainInvocation {

    private static Method invokeMethod;

    private Object target;
    private Object proxy;
    private Method method;
    private Object[] args;
    private List<Object> advices;

    static {
        try {
            invokeMethod = AopAdviceChainInvocation.class.getMethod("invoke",null);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public AopAdviceChainInvocation(Object target, Object proxy, Method method, Object[] args, List<Object> advices) {
        this.target = target;
        this.proxy = proxy;
        this.method = method;
        this.args = args;
        this.advices = advices;
    }

    // 责任链执行记录索引号
    private int i = 0;

    public Object invoke() throws Throwable{
        if(i < this.advices.size()){
            Object advice = this.advices.get(i++);

            if(advice instanceof MethodBeforeAdvice){
                //执行前置增强
                ((MethodBeforeAdvice) advice).before(method,args,target);
            }else if (advice instanceof MethodInterceptor){
                //执行环绕增强和异常处理增强。注意这里给入的method和对象是invoke方法和链对象
                return ((MethodInterceptor) advice).invoke(invokeMethod,null,this);
            }else if (advice instanceof AfterReturningAdvice){
                //当是后置增强时，先得得到结果，再执行后置增强逻辑
                Object returnValue = this.invoke();
                ((AfterReturningAdvice) advice).afterReturning(returnValue,method,args,target);
                return returnValue;
            }
            return this.invoke();
        }else {
            return method.invoke(target,args);
        }
    }
}
